package lock.ReentrantLock;

import java.util.Arrays;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @describe: 类描述信息
 * @author: morningcat.zhang
 * @date: 2019/4/22 5:07 PM
 */
public class MyArrayBlockQueue<T> {

    Lock lock = new ReentrantLock();
    Condition empty = lock.newCondition();
    Condition full = lock.newCondition();
    Integer size;
    Integer capacity;
    T[] data;

    public MyArrayBlockQueue(Integer capacity) {
        size = 0;
        this.capacity = capacity;
        data = (T[]) new Object[capacity];
    }


    public int size() {
        return size;
    }


    public void put(T t) throws InterruptedException {
        lock.lockInterruptibly();

        try {
            while (size >= capacity) {
                full.await();
            }
            size++;
            data[size - 1] = t;
            empty.signalAll();
        } finally {
            lock.unlock();
        }

    }


    public T take() throws InterruptedException {
        lock.lockInterruptibly();

        try {
            while (size < 1) {
                empty.await();
            }
            size--;
            T t = data[0];
            data = Arrays.copyOfRange(data, 1, size);
            full.signalAll();
            return t;
        } finally {
            lock.unlock();
        }
    }


}
